package cn.qfei.qiyuesuo.service.impl;

import cn.qfei.qiyuesuo.bo.*;
import cn.qfei.qiyuesuo.common.ContractConstant;
import cn.qfei.qiyuesuo.common.enums.ErrorCode;
import cn.qfei.qiyuesuo.service.*;
import cn.qfei.qiyuesuo.service.feishu.FeishuContractService;
import cn.qfei.qiyuesuo.vo.ExternalDataVo;
import cn.qfei.qiyuesuo.vo.qiyuesuo.QysContractNoticeVo;
import cn.qfei.qiyuesuo.vo.qiyuesuo.SingOptionInfo;
import cn.qfei.qiyuesuo.vo.qiyuesuo.SingOptionRes;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@Slf4j
public class FeishuNoticeServiceImpl implements FeishuNoticeService {
    @Value("${feishu.appKey}")
    private String fsAppKey;
    @Value("${feishu.accessSecret}")
    private String fsAppSecret;
    @Value("${feishu.appId}")
    private String fsAppId;
    private static String getPreSingmsg="{\"templateId\":\"ctp_AAkIyouJa5NR\",\"content\":{\"elements\":[{\"tag\":\"markdown\",\"content\":\"您有一份文件《${fileName}》需要指定签署位置，请及时查看并完成签署位置指定。\"},{\"tag\":\"action\",\"actions\":[{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"查看详情\"},\"type\":\"primary\",\"multi_url\":{\"url\":\"https://open.feishu.cn/document\",\"android_url\":\"\",\"ios_url\":\"\",\"pc_url\":\"\"}}]}],\"header\":{\"template\":\"blue\",\"title\":{\"content\":\"发起方签署位置指定待办通知\",\"tag\":\"plain_text\"}}},\"mock_data\":\"{\\\"fileName\\\":\\\"\\\"}\",\"variables\":[{\"type\":\"Text\",\"name\":\"fileName\",\"description\":\"文件名称\",\"variable_id\":0,\"config\":\"{}\"}]}";
//    private static String getPreSingmsg="{\"templateId\":\"ctp_AAkIyouJa5NR\",\"content\":{\"Elements\":[{\"tag\":\"markdown\",\"content\":\"您有一份文件需要指定签署位置，请及时查看并完成签署位置指定。\"},{\"tag\":\"action\",\"actions\":[{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"查看详情\"},\"type\":\"primary\",\"multi_url\":{\"url\":\"presingUrl\",\"android_url\":\"\",\"ios_url\":\"\",\"pc_url\":\"\"}}]}],\"header\":{\"template\":\"blue\",\"title\":{\"content\":\"发起方签署位置指定待办通知\",\"tag\":\"plain_text\"}}},\"mock_data\":\"{\\\"fileName\\\":\\\"\\\"}\",\"variables\":[{\"type\":\"Text\",\"name\":\"fileName\",\"description\":\"文件名称\",\"variable_id\":0,\"config\":\"{}\"}]}";

    //    @Value("${feishu.preSingmsg}")
//    private String preSingmsg="{\"templateId\":\"ctp_AAkIyouJa5NR\",\"content\":{\"i18nElements\":[{\"tag\":\"markdown\",\"content\":\"您有一份文件《{fileName}》需要指定签署位置，请及时查看并完成签署位置指定。\"},{\"tag\":\"action\",\"actions\":[{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"查看详情\"},\"type\":\"primary\",\"multi_url\":{\"url\":\"{presingUrl}\",\"android_url\":\"\",\"ios_url\":\"\",\"pc_url\":\"\"}}]}],\"header\":{\"template\":\"blue\",\"title\":{\"content\":\"发起方签署位置指定待办通知\",\"tag\":\"plain_text\"}}},\"mock_data\":\"{\\\"fileName\\\":\\\"\\\"}\",\"variables\":[{\"type\":\"Text\",\"name\":\"fileName\",\"description\":\"文件名称\",\"variable_id\":0,\"config\":\"{}\"}]}";
//    private String preSingmsg="{\"zh_cn\":\"{\"templateId\":\"ctp_AAkIyouJa5NR\",\"content\":{\"elements\":[{\"tag\":\"markdown\",\"content\":\"您有一份文件《${fileName}》需要指定签署位置，请及时查看并完成签署位置指定。\"},{\"tag\":\"action\",\"actions\":[{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"查看详情\"},\"type\":\"primary\",\"multi_url\":{\"url\":\"https://open.feishu.cn/document\",\"android_url\":\"\",\"ios_url\":\"\",\"pc_url\":\"\"}}]}],\"header\":{\"template\":\"blue\",\"title\":{\"content\":\"发起方签署位置指定待办通知\",\"tag\":\"plain_text\"}}},\"mock_data\":\"{\\\"fileName\\\":\\\"\\\"}\",\"variables\":[{\"type\":\"Text\",\"name\":\"fileName\",\"description\":\"文件名称\",\"variable_id\":0,\"config\":\"{}\"}]}\"}";
    @Autowired
    private KaixuanSignService kaixuanSignService;
    @Autowired
    private HankouDataService hankouDataService;

    @Autowired
    private QiyuesuoApiService qiyuesuoApiService;
    @Autowired
    private FeishuContractService feishuContractService;

    private static String SEALID_ZD_VALUE="sealId";

    //封装参数
    public FeishuNoticeBo getFeishuNoticeDTO(HttpServletRequest request) {
        FeishuNoticeBo dto = new FeishuNoticeBo();
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder jsonBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                jsonBuilder.append(line);
            }
            String jsonData = jsonBuilder.toString();
            log.info("fsEvent参数：{}", jsonData);

            dto.setNoticeStr(jsonData);
            if (StringUtils.isBlank(jsonData)) {
                return dto;
            }
            JSONObject jsonResult = JSONObject.parseObject(jsonData);
            if (StringUtils.isBlank(jsonData)) {
                return dto;
            }
            JSONObject header = jsonResult.getJSONObject("header");
            if (header != null) {
                dto.setEventId(header.getString("event_id"));
                dto.setEventType(header.getString("event_type"));
                dto.setCreateTime(header.getString("create_time"));
                dto.setToken(header.getString("token"));
                dto.setAppId(header.getString("app_id"));
                dto.setTenantKey(header.getString("tenant_key"));
            }
            JSONObject event = jsonResult.getJSONObject("event");
            if (event != null) {
                dto.setContractId(event.getString("contract_id"));
                dto.setContractStageName(event.getString("contract_stage_name"));
                dto.setContractStageCode(event.getIntValue("contract_stage_code"));
            }

        } catch (IOException e) {
            log.error("封装事件数据出错", e);
        }
        return dto;
    }

    /**
     * 处理企业锁
     *
     * @param feishuNoticeDTO
     * @return
     */
    public ErrorCode updateQysNotice(QysContractNoticeVo feishuNoticeDTO) {
        ErrorCode errorCode = ErrorCode.SUCCESS;
        String bizId = feishuNoticeDTO.getBizId();
        log.info("预盖章开始处理contractId={}", bizId);
        //获取飞书合同信息
        PreSingSendBo singSendBo= getcreateUserId(bizId, ContractConstant.USE_ID_TYPE);
        if (singSendBo==null||StringUtils.isBlank(singSendBo.getCreateUserId())){
            log.info("合同信息为空直接返回");
            return  ErrorCode.FALSE;
        }

        String preSignurl = kaixuanSignService.getPreSignurl(bizId);
        log.info("预签链接={}", preSignurl);
        if (StringUtils.isNotBlank(preSignurl)) {//发送给创建者
            String createUserId = singSendBo.getCreateUserId();
            String contractName=singSendBo.getContractName();
            String msg = getMsgToContractCreateUser(preSignurl,contractName);
            log.info("msg={}",msg);
            errorCode = sendMsgToContractCreateUser(msg, createUserId, ContractConstant.USE_ID_TYPE);
        }
        return errorCode;
    }

    @Override
    public SingOptionRes getSingOption(ExternalDataVo vo) {
        SingOptionRes res=new SingOptionRes();
        res.setCode("0");
        res.setMsg("success");
        String ourPartyName=vo.getCompanyName();
        List<SealCustomparamListBo> list=qiyuesuoApiService.getsealList(ourPartyName);
        if (list==null||list.size()==0){
            return res;
        }
        List<SingOptionInfo> singOptionList=new ArrayList<>();
        for (SealCustomparamListBo bo: list) {
            SingOptionInfo info=new SingOptionInfo();
            info.setLabel(bo.getName());
            info.setValue(bo.getId());
            singOptionList.add(info);
        }
        res.setSealId(singOptionList);
        return res;
    }

    private PreSingSendBo getcreateUserId(String bizId, String useIdType) {
        PreSingSendBo bo=new PreSingSendBo();
        Map<String, Object> map = getFsContractData(bizId);
        if (map == null || map.get("create_user_id") == null) {
            return null;
        }
        String createUserId = map.get("create_user_id") == null ? null : map.get("create_user_id").toString();
        bo.setContractName(map.get("contract_name") == null ? null : map.get("contract_name").toString());
        bo.setCreateUserId(createUserId);
        return bo;
    }

    /**
     * 处理合同事件
     *
     * @param feishuNoticeDTO
     * @return
     */
    public ErrorCode updateFeishuNotice(FeishuNoticeBo feishuNoticeDTO) {
        ErrorCode errorCode = ErrorCode.SUCCESS;
        String contractId = feishuNoticeDTO.getContractId();
        ContractNotceBo bo = new ContractNotceBo();
        getContractNodeNameFeishuInstance(contractId, bo, null);
        List<TaskInstanceBo> taskInstanceList = bo.getTaskInstanceList();
        log.info("流程任务={}", taskInstanceList);
        if (isNodeNameMatch(ContractConstant.COMMIT_SATUS, taskInstanceList)) {//合同提交
            log.info("合同创建处理contractId={}", contractId);
            String ourPartyName = bo.getOurPartyName();
            errorCode = addContract(contractId, ourPartyName,bo);
            String preSignurl=null;
            if (StringUtils.isNotBlank(contractId)){
                log.info("预盖章开始处理contractId={}",contractId);
                preSignurl= kaixuanSignService.getPreSignurl(contractId);
            }

           log.info("预签链接={}",preSignurl);
           if (StringUtils.isNotBlank(preSignurl)){//发送给创建者
           String msg=getMsgToContractCreateUser(preSignurl,bo.getContractName());
           errorCode=  sendMsgToContractCreateUser(msg,bo.getCreateUserId(),ContractConstant.USE_ID_TYPE);
           }
            return errorCode;
        }
//        if (isNodeNameMatch(ContractConstant.PRE_SEAL_SATUS,taskInstanceList)){//预盖章
//            log.info("预盖章开始处理contractId={}",contractId);
//           String preSignurl= kaixuanSignService.getPreSignurl(contractId);
//           log.info("预签链接={}",preSignurl);
//           if (StringUtils.isNotBlank(preSignurl)){//发送给创建者
//           String msg=getMsgToContractCreateUser(preSignurl);
//           errorCode=  sendMsgToContractCreateUser(msg,bo.getCreateUserId(),ContractConstant.USE_ID_TYPE);
//           }
//
//        }else
        if (isNodeNameMatch(ContractConstant.SEAL_SATUS, taskInstanceList)) {//盖章
            log.info("盖章开始处理contractId={}", contractId);
            String ourPartyName = bo.getOurPartyName();
            String sealIds=getSealIds(bo.getForm());
            errorCode = kaixuanSignService.signContractBycompany(contractId, ourPartyName,sealIds);

        } else if (isNodeNameMatch(ContractConstant.FS_CONTRACT_NAME, taskInstanceList)) {//文件回调
            List<TaskInstanceBo> taskList=  getTaskList(ContractConstant.FS_CONTRACT_NAME,  taskInstanceList);

            QysContractNoticeVo vo = new QysContractNoticeVo();
            vo.setBizId(contractId);
//            ContractNotceBo contractNotceBo = new ContractNotceBo();
//            getContractNodeNameFeishuInstance(contractId, contractNotceBo, ContractConstant.FS_CONTRACT_NAME);
            errorCode = updateContractPlace(vo, bo,taskList);
            return errorCode;
        } else {//不通直接返回
            log.info("合同状态不满足直接返回contractId={}", contractId);
            return ErrorCode.CONTRACT_SATUS_FA;
        }
//        kaixuanSignService.updateSignSatus();
        return errorCode;

    }

    private String getSealIds(String form) {
        String sealIdValue=SEALID_ZD_VALUE;
        if (StringUtils.isNotBlank(form)){
            return null;
        }
        List<Map<String,Object>> list=JSON.parseObject(form,List.class);
        if (list==null||list.size()==0){
            return null;
        }
        for (Map<String,Object> map: list ) {
            Object obj=map.get("attribute_name");
            if (obj!=null&&sealIdValue.equals(obj.toString())){
                return map.get("attribute_value")==null?null:map.get("attribute_value").toString();
            }
        }
        return null;
        //
    }

    /**
     * 添加合同
     * @param contractId
     * @param ourPartyName
     * @return
     */
    private ErrorCode addContract(String contractId, String ourPartyName,ContractNotceBo bo) {
         List<FileItemBo> fileItemBos=getFileItemBos(bo);
         if (fileItemBos==null||fileItemBos.size()==0){
             return ErrorCode.FALSE;
         }
        String contractName=bo.getContractName();
        contractId="123333333";
        String contextId= qiyuesuoApiService.addContract(fileItemBos,contractName,contractId,ourPartyName);
        log.info("生成合同id={}",contextId);
        bo.setContextId(contextId);
        return ErrorCode.SUCCESS;
    }

    private List<FileItemBo> getFileItemBos(ContractNotceBo bo) {
        List<FileItemBo> list=new ArrayList<>();
         ContractFileBo contractText=bo.getContractText();//合同主文件
        if (contractText!=null){
            FileItemBo fileItemBo=downloadFile(contractText,list);
            if (fileItemBo!=null&&fileItemBo.getFile()!=null){
                list.add(fileItemBo);
            }
        }
         List<ContractFileBo> contractCauses=bo.getContractCauses();//合同附件
        if (contractCauses!=null&&contractCauses.size()>0){
            for (ContractFileBo contractFileBo: contractCauses) {
                FileItemBo fileItemBo=downloadFile(contractFileBo,list);
                if (fileItemBo!=null&&fileItemBo.getFile()!=null){
                    list.add(fileItemBo);
                }
            }

        }
         List<ContractFileBo> contractAttachments=bo.getContractAttachments();//其他附件
        if (contractAttachments!=null&&contractAttachments.size()>0){
            for (ContractFileBo contractFileBo: contractAttachments) {
                FileItemBo fileItemBo=downloadFile(contractFileBo,list);
                if (fileItemBo!=null&&fileItemBo.getFile()!=null){
                    list.add(fileItemBo);
                }
            }

        }

        return list;
    }
    private String getStartPathName(){
        Random random = new Random();
        String name = random.nextInt(10000) +"a" +System.currentTimeMillis();
        return name;
    }
    private FileItemBo downloadFile(ContractFileBo bo ,List<FileItemBo> list){
        if (bo==null)return null;
         String fileId=bo.getFileId();
         String fileName=bo.getFileName();
         if (StringUtils.isBlank(fileId)||StringUtils.isBlank(fileName)){
             return null;
         }
        fileName=handleNameSame(fileName,list);
        File file=feishuContractService.downloadFile(fsAppId,  fsAppSecret,fileId,fileName);
        FileItemBo itemBo=new FileItemBo();
        itemBo.setFile(file);
        itemBo.setFileName(fileName);
        return itemBo;
    }

    private String handleNameSame(String fileName, List<FileItemBo> list) {
        if (StringUtils.isBlank(fileName)){}

        if (list==null||list.size()==0){
            return fileName;
        }
        String finalFileName = fileName;
        Optional<FileItemBo> op= list.stream().filter(fileItemBo -> finalFileName.equals(fileItemBo.getFileName())).findFirst();
        if (!op.isPresent()){
            return fileName;
        }
        fileName=getStartPathName()+fileName;
        return handleNameSame(fileName,list);
    }

    @Override
    public ErrorCode updateContractPlace(QysContractNoticeVo vo, ContractNotceBo bo, List<TaskInstanceBo> taskInstanceList) {
        String contractId = vo.getBizId();
        if (taskInstanceList == null || taskInstanceList.size() == 0) {
            log.info("合同节点不对之间返回");
            return ErrorCode.FALSE;
        }
        FilePathBo filePathBo = qiyuesuoApiService.getPathDowlaod(contractId);
        if (filePathBo != null) {
            filePathBo.setContractId(contractId);
            log.info("本地文件位置filePathBo={}", filePathBo);
            //飞书文件id
            String fsFileId = uploadContractFile(filePathBo);
            log.info("上传飞书的文件id={}", fsFileId);
            filePathBo.setFsFileId(fsFileId);
        }
        if (StringUtils.isNotBlank(filePathBo.getFsFileId())) {
            List<String> attachmentIds = new ArrayList<>();
            attachmentIds.add(filePathBo.getFsFileId());
            int flag = updateContract(contractId, attachmentIds);
            if (flag == 0) {
                log.info("更新合同失败processInstanceId={}", contractId);
                return ErrorCode.FALSE;
            }
        }

        //处理下一个节点
        for (TaskInstanceBo taskInstanceBo : taskInstanceList) {
            String taskInstanceId = taskInstanceBo.getTaskInstanceId();
            String assigneeIds = taskInstanceBo.getAssigneeIds();
            String processInstanceId = bo.getProcessInstanceId();
            int flag = updateInstanceAssignee(processInstanceId, taskInstanceId, assigneeIds);
            if (flag == 0) {
                log.info("更新流程节点失败processInstanceId={},contractId={}", processInstanceId, contractId);
                return ErrorCode.FALSE;
            }
        }


        log.info("更新合同完成");

        return ErrorCode.FALSE;
    }

    private boolean isNodeNameMatch(String preSealSatus, List<TaskInstanceBo> taskInstanceList) {
        List<TaskInstanceBo> taskList=  getTaskList(preSealSatus,  taskInstanceList);
        if (taskList==null||taskList.size()==0){
            return false;
        }
        return true;
    }
    private  List<TaskInstanceBo> getTaskList(String preSealSatus, List<TaskInstanceBo> taskInstanceList) {
        List<TaskInstanceBo> res=new ArrayList<>();
        if (taskInstanceList == null || taskInstanceList.size() == 0) {
            return null;
        }
        for (TaskInstanceBo taskInstanceBo : taskInstanceList) {
            if (taskInstanceBo == null) {
                continue;
            }
            if (preSealSatus.equals(taskInstanceBo.getTaskInstanceName())) {
                res.add(taskInstanceBo);
            }
        }
        return res;
    }
    public ErrorCode sendMsgToContractCreateUser(String msg, String createUserId, String receiveType) {
        String msgType = "interactive";
        int flag = feishuContractService.sendCardMessageToPeople(fsAppId, fsAppSecret, createUserId, msgType, msg, receiveType);
        if (flag != 1) {
            log.info("发送通知失败直接返回");
            return ErrorCode.FALSE;

        }
        return ErrorCode.SUCCESS;


    }

    private String getMsgToContractCreateUser(String preSignurl, String contractName) {
        String msg=getPreSingmsg;
       return msg.replace(ContractConstant.CONTRACT_NAME_TYPE,contractName).replace(ContractConstant.PRE_SING_URL_TYPE,preSignurl);
    }
    /**
     * 判断飞书合同流程是否符合
     *
     * @param contractId
     * @return
     */
    public void getContractNodeNameFeishuInstance(String contractId, ContractNotceBo bo, String contractNodeName) {
        Map<String, Object> map = getFsContractData(contractId);
        if (map == null || map.get("process_instance_id") == null) {
            return;
        }
        String processInstanceId = map.get("process_instance_id").toString();
        String createUserId = map.get("create_user_id") == null ? null : map.get("create_user_id").toString();
        String ourPartyName = getOurPartyName(map);
        bo.setCreateUserId(createUserId);
        bo.setProcessInstanceId(processInstanceId);
        bo.setOurPartyName(ourPartyName);
        bo.setContractName(map.get("contract_name") == null ? null : map.get("contract_name").toString());
        Map<String, Object> contractFiles=map.get("contract_files") == null ? null : (Map<String, Object>)map.get("contract_files");
         ContractFileBo contractText=getContractFileBo(contractFiles);//合同主文件
         List<ContractFileBo> contractCauses=getContractFileBoList(contractFiles,"contract_causes");//合同附件
         List<ContractFileBo> contractAttachments=getContractFileBoList(contractFiles,"contract_attachments");//合同附件;//其他附件
        bo.setContractAttachments(contractAttachments);
        bo.setContractText(contractText);
        bo.setContractCauses(contractCauses);
        String archiveNumber = map.get("archive_number") == null ? null : map.get("archive_number").toString();
        log.info("归档编号={}", archiveNumber);
        bo.setArchiveNumber(archiveNumber);
        bo.setForm(map.get("form") == null ? null : map.get("form").toString());

        Map<String, Object> processMap = getFsProcessInstances(processInstanceId);
        if (processMap == null) {
            return;
        }
        log.info("审批信息={}", processMap);
        getContractNodeNameFeishuInstanceByMap(processMap, bo, contractNodeName);
    }

    private List<ContractFileBo> getContractFileBoList(Map<String, Object> contractFiles, String key) {
        List<ContractFileBo> list=new ArrayList<>();
        if (contractFiles==null){
            return null;
        }
        List<Map<String, Object>> contract_text=contractFiles.get(key) == null ? null : (List<Map<String, Object>>)contractFiles.get(key);
        if (contract_text==null||contract_text.size()==0){
            return null;
        }
        for (Map<String, Object> map: contract_text ) {
            ContractFileBo bo=getContractFileBoByMap(map);
            if (bo!=null){
                list.add(bo);
            }
        }
      return list;
    }

    private ContractFileBo getContractFileBo(Map<String, Object> contractFiles) {
        if (contractFiles==null){
            return null;
        }
        Map<String, Object> contract_text=contractFiles.get("contract_text") == null ? null : (Map<String, Object>)contractFiles.get("contract_text");
       return getContractFileBoByMap(contract_text);

    }
    private ContractFileBo getContractFileBoByMap(Map<String, Object> map) {
        ContractFileBo bo=new ContractFileBo();
        if ( map==null){
            return null;
        }
        bo.setFileName(map.get("file_name") == null ? null : map.get("file_name").toString());

        bo.setFileId(map.get("file_id") == null ? null : map.get("file_id").toString());
        return bo;

    }
    @Override
    public String uploadContractFile(FilePathBo filePathBo) {
        File file = new File(filePathBo.getFilePath());
        String fileName = filePathBo.getFileName();
        return feishuContractService.uploadContractFile(filePathBo.getContractId(), fsAppId, fsAppSecret, "attachment", file, fileName);

    }

    private String uploadApprovalFile(FilePathBo filePathBo) {
        File file = new File(filePathBo.getFilePath());
        String fileName = filePathBo.getFileName();
        return feishuContractService.uploadApprovalFile(filePathBo.getContractId(), fsAppId, fsAppSecret, "attachment", file, fileName);

    }

    @Override
    public int updateContract(String contractId, List<String> attachmentIds) {
        return feishuContractService.updateContract(contractId, fsAppId, fsAppSecret, attachmentIds);

    }

    @Override
    public int updateInstanceAssignee(String processInstanceId, String taskInstanceId, String assigneeIds) {
        return feishuContractService.updateInstanceAssignee(processInstanceId, fsAppId, fsAppSecret, taskInstanceId, assigneeIds);

    }

    /**
     * 审批
     *
     * @param instanceId
     * @return
     */
    @Override
    public ApprovalExampleBo getApprovalExample(String instanceId) {
        Map<String, Object> map = feishuContractService.selectInstanceById(instanceId, fsAppId, fsAppSecret);
        if (map == null) return null;
        ApprovalExampleBo bo = new ApprovalExampleBo();
        bo.setApprovalCode(map.get("approval_code") == null ? null : map.get("approval_code").toString());
        bo.setInstanceCode(map.get("instance_code") == null ? null : map.get("instance_code").toString());
        bo.setOpenId(map.get("open_id") == null ? null : map.get("open_id").toString());
        bo.setForm(map.get("form") == null ? null : map.get("form").toString());

        List<Map<String, Object>> taskMapList = (List<Map<String, Object>>) map.get("task_list");
        List<TaskBo> taskList = new ArrayList<>();
        if (taskMapList != null && taskMapList.size() > 0) {
            bo.setTaskList(taskList);
            for (Map<String, Object> taskMap : taskMapList) {
                if (taskMap == null) {
                    continue;
                }
                TaskBo taskBo = new TaskBo();
                taskBo.setTaskId(map.get("id") == null ? null : map.get("id").toString());
                taskBo.setOpenId(map.get("open_id") == null ? null : map.get("open_id").toString());
                taskBo.setStatus(map.get("status") == null ? null : map.get("status").toString());
                taskBo.setNodeName(map.get("node_name") == null ? null : map.get("node_name").toString());

                taskList.add(taskBo);
            }
        }

        return null;
    }


    private String getOurPartyName(Map<String, Object> map) {
        if (map.get("our_party_list") == null) {
            return null;
        }
        List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("our_party_list");
        for (Map<String, Object> ourPartyMap : list) {
            if (ourPartyMap == null || ourPartyMap.get("our_party_type_code") == null || "0".equals(ourPartyMap.get("our_party_type_code").toString())) {
                return ourPartyMap.get("our_party_name") == null ? null : ourPartyMap.get("our_party_name").toString();
            }
            ;

        }
        return null;
    }

    private void getContractNodeNameFeishuInstanceByMap(Map<String, Object> processMap, ContractNotceBo bo, String contractNodeName) {
        if (processMap == null || processMap.get("task_instance_list") == null) {
            return;
        }
        List<Map<String, Object>> list = (List<Map<String, Object>>) processMap.get("task_instance_list");
        List<TaskInstanceBo> taskInstanceList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            if (map == null || map.get("node_name") == null) {
                continue;
            }
            String endTime = map.get("end_time") == null ? null : map.get("end_time").toString();
//            printTIme(endTime);
            if (StringUtils.isBlank(endTime) || endFlag(endTime)) {
                Map<String, Object> nodeNname = (Map<String, Object>) map.get("node_name");
                String nodeNnameStr = nodeNname.get("zh").toString();
                if (StringUtils.isNotBlank(contractNodeName) && !contractNodeName.equals(nodeNnameStr)) {
                    continue;
                }

                TaskInstanceBo taskInstanceBo = new TaskInstanceBo();
                taskInstanceBo.setTaskInstanceName(nodeNnameStr);
                taskInstanceBo.setTaskInstanceId(map.get("task_instance_id") == null ? null : map.get("task_instance_id").toString());
                if (map.get("assignee_ids") != null) {
                    List<Object> assigneeList = (List<Object>) map.get("assignee_ids");
                    taskInstanceBo.setAssigneeIds(getFistAssigneeId(assigneeList));
                }
                taskInstanceList.add(taskInstanceBo);
            }
            bo.setTaskInstanceList(taskInstanceList);
        }
    }

    private void printTIme(String endTime) {
        if (StringUtils.isBlank(endTime)) {
            return;
        }
//        Instant instant = Instant.ofEpochSecond(Long.valueOf(endTime));
        Date dateTime = new Date(Long.valueOf(endTime));
        SimpleDateFormat DATETIME_FULL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
        // 格式化日期时间
        String formattedDate = DATETIME_FULL.format(dateTime);
        System.out.println(formattedDate);
    }

    private String getFistAssigneeId(List<Object> assigneeList) {
        if (assigneeList == null || assigneeList.size() == 0) {
            return null;
        }
        Object objId = assigneeList.get(0);
        return objId == null ? null : objId.toString();
    }

    private boolean endFlag(String endTime) {
        if (StringUtils.isBlank(endTime)) {
            return true;
        }
        return Long.valueOf(endTime) >= new Date().getTime();
    }

    public static void main1(String[] args) {
        // 假设这是您的时间戳（单位：秒）
//        long timestamp = 1625746540L;
        Calendar calendar = Calendar.getInstance();
// 设置时间为1970年1月1日00:00:66
        calendar.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
//        calendar.set(Calendar.MILLISECOND,0);
        long timestamp1970 = calendar.getTimeInMillis();
        LocalDateTime dateTime = LocalDateTime.now();
        // 将时间戳转换为LocalDateTime
//        Instant instant = Instant.ofEpochSecond(newTIme);
//        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

        // 格式化日期时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDate = dateTime.format(formatter);

        // 输出格式化后的日期时间
        System.out.println(formattedDate);


        System.out.println(new Date().getTime());
        long s = System.currentTimeMillis();
        System.out.println(s);

    }

    private Map<String, Object> getFsProcessInstances(String processInstanceId) {
//        String accessToken = authService.tenantAccessToken( fsAppId, fsAppSecret,fsAppKey);
        return feishuContractService.getFsProcessInstances(fsAppId, fsAppSecret, processInstanceId);
    }


    private Map<String, Object> getFsContractData(String contractId) {
//        String accessToken = authService.tenantAccessToken( fsAppId, fsAppSecret,fsAppKey);
        return feishuContractService.selectContractById(contractId, fsAppId, fsAppSecret, null, fsAppKey, null);
    }

    @Override
    public int tasksApprov(FilePathBo filePathBo, TaskBo taskBo, ApprovalExampleBo bo) {
        String taskId = taskBo.getTaskId();
        String openId = taskBo.getOpenId();
        String fsFileId = filePathBo.getFsFileId();
        String approvalCode = bo.getApprovalCode();//审批定义 Code
        String form=bo.getForm();
        String instanceCode = bo.getInstanceCode();//审批实例 Code
        return feishuContractService.tasksApprov(approvalCode, fsAppId, fsAppSecret, instanceCode, fsFileId, openId, taskId,form);

    }

    @Override
    public ErrorCode updateSpPlace(FeishuSpBo vo) {
        String approvalCode = vo.getApprovalCode();
        ApprovalExampleBo bo = getApprovalExample(approvalCode);
        if (bo == null || bo.getTaskList() == null || bo.getTaskList() == null) {
            log.info("查询审批实例不存在");
            return ErrorCode.FALSE;
        }

        List<TaskBo> taskList = bo.getTaskList();
        List<TaskBo> needTaskNode = getNeedTaskNode(taskList, ContractConstant.SP_CONTRACT_NAME);
        if (needTaskNode == null || needTaskNode.size() == 0) {
            log.info("合同节点不对之间返回");
            return ErrorCode.FALSE;
        }
        FilePathBo filePathBo = qiyuesuoApiService.getPathDowlaod(approvalCode);
        if (filePathBo == null || StringUtils.isBlank(filePathBo.getFilePath())) {
            log.info("文件不存在直接返回");
        }
        filePathBo.setContractId(approvalCode);
        log.info("本地文件位置filePathBo={}", filePathBo);
        //飞书文件id
        String fsFileId = uploadApprovalFile(filePathBo);
        log.info("上传飞书的文件id={}", fsFileId);
        filePathBo.setFsFileId(fsFileId);
        String from=getFrom(fsFileId);
        bo.setForm(from);
        for (TaskBo taskBo : needTaskNode) {
            //开始处理更新id
            log.info("更新合同完成");
            int flag = tasksApprov(filePathBo, taskBo, bo);
        }
        return ErrorCode.SUCCESS;
    }

    private String getFrom(String fsFileId) {
        List<Map<String,Object>> list=new ArrayList<>();
        Map<String,Object> map=new HashMap<>();
        map.put("id","attachmentId");
        map.put("type","attachmentV2");
        map.put("value","fsFileId");
        list.add(map);
//[{"id":"111", "type": "input", "value":"test"}]"
        return JSON.toJSONString(list);
    }

    public static void main(String[] args) {
        String s=getPreSingmsg;
        Map<String,Object> list= JSON.parseObject(s,Map.class);


        System.out.println(list);

    }

    private List<TaskBo> getNeedTaskNode(List<TaskBo> taskLis, String fsContractName) {
        List<TaskBo> reList = new ArrayList<>();
        if (taskLis == null || taskLis.size() == 0) {
            return null;
        }

        for (TaskBo taskBo : taskLis) {
            if (taskBo == null) {
                continue;
            }
            if (!("PENDING".equals(taskBo.getStatus()) || "TRANSFERRED".equals(taskBo.getStatus()))) {
                log.info("任务状态{},跳过", taskBo.getStatus());
            }
            if (!fsContractName.equals(taskBo.getNodeName())) {
                log.info("节点名不对{},跳过", taskBo.getNodeName());

            }

            reList.add(taskBo);

        }
        return reList;
    }


    public FeishuSpBo getFeishuNoticeSpDTO(HttpServletRequest request) {
        FeishuSpBo dto = new FeishuSpBo();
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder jsonBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                jsonBuilder.append(line);
            }
            String jsonData = jsonBuilder.toString();
            log.info("fsEvent参数：{}", jsonData);

            if (StringUtils.isBlank(jsonData)) {
                return dto;
            }
            JSONObject jsonResult = JSONObject.parseObject(jsonData);
            if (StringUtils.isBlank(jsonData)) {
                return dto;
            }
            dto.setEventType(jsonResult.getString("type"));
            JSONObject event = jsonResult.getJSONObject("event");
            if (event != null) {
                dto.setApprovalCode(event.getString("approval_code"));
                dto.setInstanceCode(event.getString("instance_code"));
                dto.setTaskId(event.getString("task_id"));
            }
        } catch (IOException e) {
            log.error("封装事件数据出错", e);
        }
        return dto;
    }


}
